﻿using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Threading;

namespace TechNewLogic.GraphIT.Printing
{
	class XpsDocumentGenerator
	{
		private readonly Visual _mainPrintContent;
		private readonly IEnumerable<PrintContent> _additionalPrintContent;
		private readonly IViewDrawingState _viewDrawingState;
		private readonly int _width;
		private readonly int _height;
		private readonly int _pageMargin;

		private IDisposable _currentRenderToken;

		internal XpsDocumentGenerator(
			Visual mainPrintContent,
			IEnumerable<PrintContent> additionalPrintContent,
			IViewDrawingState viewDrawingState,
			int width,
			int height,
			int pageMargin)
		{
			_mainPrintContent = mainPrintContent;
			_additionalPrintContent = additionalPrintContent;
			_viewDrawingState = viewDrawingState;
			_width = width;
			_height = height;
			_pageMargin = pageMargin;
		}

		internal void Print(Action<FixedDocumentSequence> finishCallback)
		{
			if (_currentRenderToken != null)
				_currentRenderToken.Dispose();

			var renderWindow = new RenderWindow(_mainPrintContent, _viewDrawingState, _width, _height, _pageMargin);
			_currentRenderToken = renderWindow;

			renderWindow.Print(layoutedVisual =>
				{
					var printLayouter = new PrintLayouter(layoutedVisual, _additionalPrintContent)
					{
						Margin = new Thickness(_pageMargin)
					};

					ThreadPool.QueueUserWorkItem(o =>
						printLayouter.Dispatcher.Invoke(() =>
						{
							var size = new Size(_width, _height);
							printLayouter.Measure(size);
							printLayouter.Arrange(new Rect(size));

							var xps = printLayouter.ToXps();
							printLayouter.ReleaseContent();
							finishCallback(xps);
						}));
				});
		}
	}
}
